﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using MyImdb.Common;
using MyImdb.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace MyImdb.ViewModel
{
    /// <summary>
    /// ViewModel for Search View
    /// </summary>
    internal class SearchViewModel: ViewModelBase
    {
        /// <summary>
        /// The _ search text
        /// </summary>
        private string _SearchText;
        /// <summary>
        /// Gets or sets the search text.
        /// </summary>
        /// <value>
        /// The search text.
        /// </value>
        public string SearchText
        {
            get { return _SearchText; }
            set
            {
                _SearchText = value;
                RaisePropertyChanged("SearchText");
            }
        }

        /// <summary>
        /// The _ search result
        /// </summary>
        private ObservableCollection<ImdbItem> _SearchResult;
        /// <summary>
        /// Gets or sets the search result.
        /// </summary>
        /// <value>
        /// The search result.
        /// </value>
        public ObservableCollection<ImdbItem> SearchResult
        {
            get { return _SearchResult; }
            set
            {
                _SearchResult = value;
                RaisePropertyChanged("SearchResult");
            }
        }

        /// <summary>
        /// The _ selected imdb item
        /// </summary>
        private ImdbItem _SelectedImdbItem;
        /// <summary>
        /// Gets or sets the selected imdb item.
        /// </summary>
        /// <value>
        /// The selected imdb item.
        /// </value>
        public ImdbItem SelectedImdbItem
        {
            get { return _SelectedImdbItem; }
            set
            {
                _SelectedImdbItem = value;
                RaisePropertyChanged("SelectedImdbItem");
            }
        }

        /// <summary>
        /// The _ loading visibility
        /// </summary>
        private Visibility _LoadingVisibility;
        /// <summary>
        /// Gets or sets the loading visibility.
        /// </summary>
        /// <value>
        /// The loading visibility.
        /// </value>
        public Visibility LoadingVisibility
        {
            get { return _LoadingVisibility; }
            set
            {
                _LoadingVisibility = value;
                RaisePropertyChanged("LoadingVisibility");
            }
        }

        /// <summary>
        /// The _ info text
        /// </summary>
        private string _InfoText;
        /// <summary>
        /// Gets or sets the info text.
        /// </summary>
        /// <value>
        /// The info text.
        /// </value>
        public string InfoText
        {
            get { return _InfoText; }
            set
            {
                _InfoText = value;
                RaisePropertyChanged("InfoText");
            }
        }

        private Settings _AppSettings;
        public Settings AppSettings
        {
            get { return _AppSettings; }
            set
            {
                _AppSettings = value;
                RaisePropertyChanged("AppSettings");
            }
        }

        /// <summary>
        /// The _ search command
        /// </summary>
        private ICommand _SearchCommand;
        /// <summary>
        /// Gets or sets the search command.
        /// </summary>
        /// <value>
        /// The search command.
        /// </value>
        public ICommand SearchCommand
        {
            get { return _SearchCommand; }
            set
            {
                _SearchCommand = value;
                RaisePropertyChanged("SearchCommand");
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SearchViewModel" /> class.
        /// </summary>
        public SearchViewModel()
        {
            SearchCommand = new RelayCommand(Search);
            LoadingVisibility = Visibility.Collapsed;
            ReadSettings();
        }

        /// <summary>
        /// Searches this instance.
        /// </summary>
        public void Search()
        {
            var isSearchTextValid = ValidateSearchText();

            if (isSearchTextValid)
            {
                var url = ServiceHelper.CreateSearchRequestUrl(SearchText);
                LoadingVisibility = Visibility.Visible;
                InfoText = string.Empty;
                SearchResult = null;

                ServiceHelper.GetSearchRequest(url, response =>
                {
                    if (response != null)
                    {
                        var searchResult = response.Where(t => !string.IsNullOrEmpty(t.Poster));
                        SearchResult = searchResult.ToObservableCollection();

                        if (SearchResult.Count == 0)
                        {
                            
                        }
                    }
                    else
                    {
                        InfoText = "No Titles Found, Try Searching Again.";
                    }
                    
                    LoadingVisibility = Visibility.Collapsed;
                }); 
            }
        }

        /// <summary>
        /// Validates the search text.
        /// </summary>
        /// <returns></returns>
        private bool ValidateSearchText()
        {
            if (!string.IsNullOrEmpty(SearchText))
            {
                var searchText = SearchText.Trim();
                if (!string.IsNullOrEmpty(searchText))
                {
                    return true;
                }
                else
                {
                    return false;
                }
                SearchText = searchText;
            }
            else
            {
                return false;
            }
        }

        private void ReadSettings()
        {
            AppSettings = FileHelper.ReadSettings();
            FileHelper.DatabaseBasePath = AppSettings.DatabasePath;
        }

        /// <summary>
        /// Downloads the specified element.
        /// </summary>
        /// <param name="element">The element.</param>
        public void Download(UIElement element)
        {
            if (FileHelper.IsDatabaseExist(AppSettings.DatabasePath))
            {
                FileHelper.DatabaseBasePath = AppSettings.DatabasePath;

                var titleExists = VerifyFileExistence(SelectedImdbItem.ImdbId);

                if (!titleExists)
                {
                    InfoText = "Downloading ...";
                    var url = ServiceHelper.CreateImdbItemRequestUrl(SelectedImdbItem.ImdbId);
                    ServiceHelper.GetImdbItemDetails(url, response =>
                    {
                        var titleDetails = response;
                        if (titleDetails != null)
                        {
                            var pngFilePath = Path.Combine(FileHelper.DatabaseBasePath, string.Format("{0}.png", titleDetails.ImdbId));
                            FileHelper.SaveToPng(element, pngFilePath);

                            var downloadingImdbItem = titleDetails;
                            downloadingImdbItem.Poster = string.Format("{0}.png", titleDetails.ImdbId);
                            var imdbContext = JsonConvert.SerializeObject(downloadingImdbItem);
                            var textFilePath = Path.Combine(FileHelper.DatabaseBasePath, string.Format("{0}.txt", titleDetails.ImdbId));

                            FileHelper.SaveImdbTitle(imdbContext, textFilePath);

                            InfoText = "Download Succeeded.";
                        }
                        else
                        {
                            //Network Issue
                            InfoText = "Download Failed, Try Again.";
                        }
                    });
                }
                else
                {
                    InfoText = "You Have Already Downloaded This Title.";
                } 
            }
            else
            {
                InfoText = "Database path is not set, cannot download. Go to settings and set database path.";
            }
        }

        /// <summary>
        /// Verifies the file existence.
        /// </summary>
        /// <param name="imdbId">The imdb id.</param>
        /// <returns></returns>
        private bool VerifyFileExistence(string imdbId)
        {
            var pngFilePath = Path.Combine(FileHelper.DatabaseBasePath, string.Format("{0}.png", imdbId));
            var textFilePath = Path.Combine(FileHelper.DatabaseBasePath, string.Format("{0}.txt", imdbId));

            var imageExists = File.Exists(pngFilePath);
            var textExists = File.Exists(textFilePath);

            if (imageExists || textExists)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Checks the directory existence.
        /// </summary>
        private void CheckDirectoryExistence()
        {
            var isPathAvailable = Directory.Exists(FileHelper.DatabaseBasePath);

            if (!isPathAvailable)
            {
                Directory.CreateDirectory(FileHelper.DatabaseBasePath);
            }
        }
    }
}
